package com.cencat.merchant.service;

import com.cencat.merchant.entity.DispatchRecordEntity;
import com.cencat.merchant.entity.DriverEntity;
import java.util.List;
import java.util.Map;

/**
 * 智能派单算法服务接口
 * 
 * @author cencat
 * @since 2024
 */
public interface DispatchAlgorithmService {
    
    /**
     * 距离优先派单算法
     * 根据司机与订单的距离进行排序，选择最近的司机
     * 
     * @param orderId 订单ID
     * @param availableDrivers 可用司机列表
     * @param orderLocation 订单位置信息(经纬度)
     * @return 最优司机ID
     */
    Long distancePriorityDispatch(Long orderId, List<DriverEntity> availableDrivers, Map<String, Double> orderLocation);
    
    /**
     * 评分优先派单算法
     * 根据司机的综合评分进行排序，选择评分最高的司机
     * 
     * @param orderId 订单ID
     * @param availableDrivers 可用司机列表
     * @param minRating 最低评分要求
     * @return 最优司机ID
     */
    Long ratingPriorityDispatch(Long orderId, List<DriverEntity> availableDrivers, Double minRating);
    
    /**
     * 负载均衡派单算法
     * 根据司机当前的订单负载情况进行派单，优先选择负载较轻的司机
     * 
     * @param orderId 订单ID
     * @param availableDrivers 可用司机列表
     * @return 最优司机ID
     */
    Long loadBalanceDispatch(Long orderId, List<DriverEntity> availableDrivers);
    
    /**
     * 专属绑定派单算法
     * 根据司机与商家的绑定关系进行派单，优先选择专属司机
     * 
     * @param orderId 订单ID
     * @param merchantId 商家ID
     * @param availableDrivers 可用司机列表
     * @return 最优司机ID
     */
    Long exclusiveBindDispatch(Long orderId, Long merchantId, List<DriverEntity> availableDrivers);
    
    /**
     * 综合智能派单算法
     * 综合考虑距离、评分、负载等多个因素进行派单
     * 
     * @param orderId 订单ID
     * @param merchantId 商家ID
     * @param availableDrivers 可用司机列表
     * @param orderLocation 订单位置信息
     * @param algorithmWeights 算法权重配置
     * @return 最优司机ID
     */
    Long intelligentDispatch(Long orderId, Long merchantId, List<DriverEntity> availableDrivers, 
                           Map<String, Double> orderLocation, Map<String, Double> algorithmWeights);
    
    /**
     * 获取可用司机列表
     * 根据订单信息和派单规则筛选可用的司机
     * 
     * @param orderId 订单ID
     * @param merchantId 商家ID
     * @param orderLocation 订单位置信息
     * @param maxDistance 最大派单距离
     * @return 可用司机列表
     */
    List<DriverEntity> getAvailableDrivers(Long orderId, Long merchantId, Map<String, Double> orderLocation, Double maxDistance);
    
    /**
     * 计算司机与订单的距离
     * 
     * @param driverLocation 司机位置(经纬度)
     * @param orderLocation 订单位置(经纬度)
     * @return 距离(公里)
     */
    Double calculateDistance(Map<String, Double> driverLocation, Map<String, Double> orderLocation);
    
    /**
     * 计算司机匹配度分数
     * 综合考虑距离、评分、负载等因素计算匹配度
     * 
     * @param driver 司机信息
     * @param orderId 订单ID
     * @param orderLocation 订单位置
     * @param weights 权重配置
     * @return 匹配度分数(0-100)
     */
    Double calculateMatchScore(DriverEntity driver, Long orderId, Map<String, Double> orderLocation, Map<String, Double> weights);
    
    /**
     * 执行派单操作
     * 创建派单记录并通知司机
     * 
     * @param orderId 订单ID
     * @param driverId 司机ID
     * @param algorithmType 派单算法类型
     * @param matchScore 匹配度分数
     * @param distance 派单距离
     * @return 派单记录
     */
    DispatchRecordEntity executeDispatch(Long orderId, Long driverId, Integer algorithmType, 
                                       Double matchScore, Double distance);
    
    /**
     * 重新派单
     * 当司机拒绝或超时未接单时，重新进行派单
     * 
     * @param dispatchRecordId 原派单记录ID
     * @param excludeDriverIds 排除的司机ID列表
     * @return 新的派单记录
     */
    DispatchRecordEntity redispatch(Long dispatchRecordId, List<Long> excludeDriverIds);
    
    /**
     * 取消派单
     * 
     * @param dispatchRecordId 派单记录ID
     * @param cancelReason 取消原因
     * @return 是否取消成功
     */
    Boolean cancelDispatch(Long dispatchRecordId, String cancelReason);
}